﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace MefBasic.Behaviors
{
    public class DoubleClickBehavior 
    {
        private const string CommandName = "Command";
        private const string CommandParameterName = "CommandParameter";

        public static DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached(CommandName, typeof (ICommand), typeof (DoubleClickBehavior), new UIPropertyMetadata(OnPropertyChanged));

        public static void SetCommand(DependencyObject target, ICommand value)
        {
            target.SetValue(CommandProperty, value);
        }

        public static DependencyProperty CommandParameterProperty =
            DependencyProperty.RegisterAttached(CommandParameterName, typeof(object), typeof(DoubleClickBehavior), new UIPropertyMetadata(OnPropertyChanged));

        public static void SetCommandParameter(DependencyObject target, object value)
        {
            target.SetValue(CommandParameterProperty, value);
        }

        /// <exception cref="InvalidOperationException">This behavior can be attached to Control item only.</exception>
        private static void OnPropertyChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
        {
            var element = target as Control;
            if (element == null)
                throw new InvalidOperationException("This behavior can be attached to Control item only.");
            switch (e.Property.Name)
            {
                case CommandName:
                    SubscribeOrUnsubscribeEvent(element, e);
                    break;
            }
        }

        private static void SubscribeOrUnsubscribeEvent(Control element, DependencyPropertyChangedEventArgs e)
        {
            if ((e.NewValue != null) && (e.OldValue == null))
            {
                element.MouseDoubleClick += HandleEvent;
            }
            else if ((e.NewValue == null) && (e.OldValue != null))
            {
                element.MouseDoubleClick -= HandleEvent;
            }
        }

        private static void HandleEvent(object sender, MouseButtonEventArgs mouseButtonEventArgs)
        {
            var element = (Control) sender;
            var command = (ICommand) element.GetValue(CommandProperty);
            var commandParameter = element.GetValue(CommandParameterProperty);
            command.Execute(commandParameter);
        }
    }
}